#ifndef __WIZ_ARCHIVE_READER_BASE_HPP__SHANHAOBO_19800429__
#define __WIZ_ARCHIVE_READER_BASE_HPP__SHANHAOBO_19800429__

#include "./WizArchiveForwardDeclare.hpp"

#include "./WizArchiveBase.hpp"

#include "./WizArchiveSerializerReaderBase.hpp"
#include "./WizArchiveSerializerReaderPointer.hpp"

namespace Wiz
{
    namespace Archive
    {
        namespace Reader
        {
            namespace Base
            {
                struct Type : public ::Wiz::Noncopyable::Type
                {
                    ::Wiz::Void::Type ReadObject(
                        ::Wiz::Void::Ptr                                InDataPtr, 
                        ::Wiz::Archive::Serializer::Reader::Base::Ptr   InLoaderPtr
                    )
                    {
                        InLoaderPtr->ReadObjectData(*this, InDataPtr);
                    }

                    ::Wiz::Void::Type ReadPointer(
                        ::Wiz::Void::Ptr                                InDataPtr, 
                        ::Wiz::Archive::Serializer::Reader::Ptr::Ptr    InLoaderPtr
                        )
                    {
                        InLoaderPtr->ReadObjectPtr(*this, InDataPtr);
                    }
                };
            } /// end of namespace Base

            namespace LoadNormalMethod
            {
                template<ArchiveT>
                struct Type
                {
                    template<class DataT>
                    static void Invoke(ArchiveT &InArchive, const DataT &InData)
                    {
                        typedef ::Wiz::NISingleton::Type< ::Wiz::Archive::Serializer::Reader::Type<ArchiveT, DataT> > tSingleton;

                        InArchive.ReadObject(
                            &InData,
                            tSingleton::SingletonPtr()
                            );
                    }
                };
            } /// end of namespace LoadNormalMethod

            namespace LoadPtrMethod
            {
                template<ArchiveT>
                struct Type
                {
                    template<class DataT>
                    static void Invoke(ArchiveT &InArchive, const DataT &InData)
                    {
                        typedef ::Wiz::NISingleton::Type< ::Wiz::Archive::Serializer::Reader::Type<ArchiveT, DataT> > tSingleton;

                        InArchive.ReadPointer(
                            &InData,
                            tSingleton::SingletonPtr()
                            );
                    }
                };
            } /// end of namespace LoadPtrMethod

            template<class ArchiveT, class DataT>
            WIZ_INLINE ::Wiz::Void::Type Read(ArchiveT& InArchive, DataT& InData, ::Wiz::Archive::VerNum::In InVer)
            {
                typedef typename ::Wiz::TypeTraits::If_<
                    ::Wiz::TypeTraits::Is::Pointer<DataT>,
                    ::Wiz::Archive::Reader::LoadPtrMethod::Type<ArchiveT>,
                    ::Wiz::Archive::Reader::LoadNormalMethod::Type<ArchiveT>
                >::tType tMethod;

                tMethod::Invoke(InArchive, InData);
            }

        } /// end of namespace Reader
    } /// end of namespace Archive
} /// end of namespace Wiz

#endif /*__WIZ_ARCHIVE_READER_BASE_HPP__SHANHAOBO_19800429__*/
